home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint96sb.zoo / src / xbios.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-21  |  5.6 KB  |  245 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
  3. */
  4.  
  5. /*
  6.  * XBIOS replacement routines
  7.  */
  8.  
  9. #include "mint.h"
  10.  
  11. extern int tosvers;    /* from main.c */
  12.  
  13. #define XBIOS_MAX 0x80
  14.  
  15. Func xbios_tab[XBIOS_MAX];    /* initially all zeros */
  16. short xbios_max = XBIOS_MAX;
  17.  
  18. /* NOTE: has_bconmap is initialized in main.c */
  19.  
  20. int has_bconmap;    /* flag: set if running under a version
  21.              * of TOS which supports Bconmap
  22.              */
  23.  
  24. /*
  25.  * Supexec() presents a lot of problems for us: for example, the user
  26.  * may be calling the kernel, or may be changing interrupt vectors
  27.  * unexpectedly. So we play some dirty tricks here: the function
  28.  * call is treated like a signal handler, and we take advantage
  29.  * of the fact that no context switches will take place while
  30.  * in supervisor mode. ASSUMPTION: the user will not choose to
  31.  * switch back to user mode, or if s/he does it will be as part
  32.  * of a longjmp().
  33.  *
  34.  * BUG: if the user function switches to user mode, then back to
  35.  * supervisor mode and returns, then the returned value may be
  36.  * inaccurate (this happens if two programs make Supexec calls
  37.  * at the same time).
  38.  */
  39.  
  40. static long ARGS_ON_STACK (*usrcall) P_((long,long,long,long,long));
  41. static long usrret;
  42. static long usrarg1, usrarg2, usrarg3, usrarg4, usrarg5;
  43.  
  44. static void ARGS_ON_STACK do_usrcall P_((void));
  45.  
  46. static void ARGS_ON_STACK
  47. do_usrcall()
  48. {
  49.     usrret = (*usrcall)(usrarg1, usrarg2, usrarg3, usrarg4, usrarg5);
  50. }
  51.  
  52. long ARGS_ON_STACK
  53. supexec(funcptr, arg1, arg2, arg3, arg4, arg5)
  54.     Func funcptr;
  55.     long arg1, arg2, arg3, arg4, arg5;
  56. {
  57.     short savesr;
  58.     CONTEXT *syscall = &curproc->ctxt[SYSCALL];
  59.  
  60. /* set things up so that "signal 0" will be handled by calling the user's
  61.  * function.
  62.  */
  63.  
  64.     usrcall = funcptr;
  65.     usrarg1 = arg1;
  66.     usrarg2 = arg2;
  67.     usrarg3 = arg3;
  68.     usrarg4 = arg4;
  69.     usrarg5 = arg5;
  70.     curproc->sighandle[0] = (long)do_usrcall;
  71.     savesr = syscall->sr;    /* save old super/user mode flag */
  72.     syscall->sr |= 0x2000;    /* set supervisor mode */
  73.     handle_sig(0);        /* actually call out to the user function */
  74.     syscall->sr = savesr;
  75.  
  76. /* do_usrcall saves the user's return value in usrret */
  77.     return usrret;
  78. }
  79.  
  80.  
  81. /*
  82.  * midiws: we have to replace this, because it's possible that the process'
  83.  * view of what the MIDI port is has been changed by Fforce or Fmidipipe
  84.  */
  85.  
  86. long ARGS_ON_STACK
  87. midiws(cnt, buf)
  88.     int cnt;
  89.     const char *buf;
  90. {
  91.     FILEPTR *f;
  92.     long towrite = cnt+1;
  93.  
  94.     f = curproc->handle[-5];    /* MIDI output handle */
  95.     if (!f) return EIHNDL;
  96.  
  97.     if (is_terminal(f)) {
  98.         while (cnt >= 0) {
  99.             tty_putchar(f, (long)*buf, RAW);
  100.             buf++; cnt--;
  101.         }
  102.         return towrite;
  103.     }
  104.     return (*f->dev->write)(f, buf, towrite);
  105. }
  106.  
  107. /*
  108.  * Modem control things: these are replaced because we handle
  109.  * Bconmap ourselves
  110.  */
  111.  
  112. /* mapin: utility routine, does a Bconmap and keeps track
  113.  * so we call the kernel only when necessary; call this
  114.  * only if has_bconmap is "true".
  115.  * Returns: 0 on failure, 1 on success.
  116.  */
  117. int curbconmap;
  118.  
  119. int
  120. mapin(dev)
  121.     int dev;
  122. {
  123.     long r;
  124.  
  125.     if (dev == curbconmap)
  126.         return 1;
  127.     r = Bconmap(dev);
  128.     if (r) {
  129.         curbconmap = dev;
  130.         return 1;
  131.     }
  132.     return 0;
  133. }
  134.     
  135. long ARGS_ON_STACK
  136. uiorec(dev)
  137.     int dev;
  138. {
  139.     TRACE(("Iorec(%d)", dev));
  140.     if (dev == 0 && has_bconmap)
  141.         mapin(curproc->bconmap);
  142.     return (long)Iorec(dev);
  143. }
  144.  
  145. long ARGS_ON_STACK
  146. rsconf(baud, flow, uc, rs, ts, sc)
  147.     int baud, flow, uc, rs, ts, sc;
  148. {
  149.     static int oldbaud = -1;
  150.     int ret_oldbaud = 0;
  151.     long rsval;
  152.     IOREC_T *ior;
  153.  
  154.     TRACE(("Rsconf(%d,%d,%d,%d,%d,%d)", baud, flow,
  155.         uc, rs, ts, sc));
  156.  
  157.     if (has_bconmap)
  158.         mapin(curproc->bconmap);
  159.     else if (tosvers < 0x0104) {
  160. /*
  161.   If this is an old TOS, try to rearrange things to support
  162.   the following Rsconf() features:
  163.     1. Rsconf(-2, ...) does not return current baud (it crashes)
  164.         -> keep track of old speed in static variable
  165.     2. Rsconf(b, ...) sends ASCII DEL to the modem unless b == -1
  166.         -> make speed parameter -1 if new speed matches old speed
  167.     3. Rsconf() discards any buffered output
  168.         -> use Iorec() to ensure all buffered data was sent before call
  169. */
  170.         if (baud == -2) {
  171.             ret_oldbaud = 1;
  172.             baud = -1;
  173.         } else if (baud == oldbaud)
  174.             baud = -1;
  175.         else if (baud > -1)
  176.             oldbaud = baud;
  177.         ior = ((IOREC_T *) uiorec(0)) + 1; /* output record */
  178.         while (ior->head != ior->tail) {
  179.             TRACE(("Rsconf() napping until transmit buf empty"));
  180.             nap(200);
  181.         }
  182.     }
  183.     rsval = Rsconf(baud, flow, uc, rs, ts, sc);
  184.     if (ret_oldbaud)
  185.         rsval = (long) oldbaud;
  186.     return rsval;
  187. }
  188.  
  189. long ARGS_ON_STACK
  190. bconmap(dev)
  191.     int dev;
  192. {
  193.     int old = curproc->bconmap;
  194.  
  195.     TRACE(("Bconmap(%d)", dev));
  196.  
  197.     if (has_bconmap) {
  198.         if (dev == -1) return old;
  199.         if (dev == -2) return Bconmap(-2);
  200.         if (dev == 0) return 0;  /* the user's just testing */
  201.         if (mapin(dev) == 0) {
  202.             DEBUG(("Bconmap: mapin(%d) failed", dev));
  203.             return 0;
  204.         }
  205.         if (set_auxhandle(curproc, dev) == 0) {
  206.             DEBUG(("Bconmap: Couldn't change AUX:"));
  207.             return 0;
  208.         }
  209.         curproc->bconmap = dev;
  210.         return old;
  211.     }
  212.     return EINVFN;    /* no Bconmap available */
  213. }
  214.  
  215. /*
  216.  * cursconf(): this gets converted into an ioctl() call on
  217.  * the appropriate device
  218.  */
  219.  
  220. long ARGS_ON_STACK
  221. cursconf(cmd, op)
  222.     int cmd, op;
  223. {
  224.     FILEPTR *f;
  225.  
  226.     f = curproc->handle[-1];
  227.     if (!f || !is_terminal(f))
  228.         return EINVFN;
  229.     return
  230.       (*f->dev->ioctl)(f, TCURSOFF+cmd, &op);
  231. }
  232.  
  233. void
  234. init_xbios()
  235. {
  236.     curbconmap = (has_bconmap) ? (int) Bconmap(-1) : 1;
  237.  
  238.     xbios_tab[0x0c] = midiws;
  239.     xbios_tab[0x0e] = uiorec;
  240.     xbios_tab[0x0f] = rsconf;
  241.     xbios_tab[0x15] = cursconf;
  242.     xbios_tab[0x26] = supexec;
  243.     xbios_tab[0x2c] = bconmap;
  244. }
  245.